home *** CD-ROM | disk | FTP | other *** search
-
- #include "intern.h"
-
- static int valid_item(OBJECT *tree, int obj)
- {
- int type;
- int ret = 0;
-
- type = get_obtype(tree, obj, NULL);
- if (type == G_STRING || type == G_SHORTCUT)
- {
- if (!get_state(tree, obj, DISABLED) && get_flag(tree, obj, SELECTABLE))
- ret = 1;
- }
- return ret;
- }
-
- /*
- * Emulation/Erweiterung von menu_popup().
- * Falls Button = 0 und das System menu_popup() hat, wird dieses aufgerufen.
- * Ist Button = 1/2 (linke/rechte Maustaste), wird das Popup selbst verwaltet.
- * Es geht dann z.B. sofort auf (nicht wie bei menu_popup() erst beim Loslassen
- * der Taste).
- * offset gibt den Offset zwischen Root und dem ersten Popup-String an (i.d.R.
- * ist offset 0, bei einem Farb-Popup aber z.B. nicht).
- */
- int cf_menu_popup(MENU *m1, int x, int y, MENU *m2, int button, int offset)
- {
- int i, d;
-
- if ((button == 0) && appl_xgetinfo(9, &d, &i, &d, &d) && (i == 1)) /* gibts menu_popup? */
- return menu_popup(m1, x, y, m2);
- else
- {
- OBJECT *tree;
- int root, m_x, m_y, event, item, but,
- msg[8], olditem, kstate;
- GRECT box, r;
- MFDB save;
- #ifdef __MTAES__
- EVNTDATA ev;
- GRECT n = {0,0,0,0};
- #endif
-
- tree = m1->mn_tree;
- root = m1->mn_menu;
- item = m1->mn_item;
-
- tree[root].ob_x = x;
- tree[root].ob_y = y - ((item - offset - root - 1) * tree[item].ob_height);
-
- /* bei RSM liegt der das Popup enthaltende Dialog nicht unbedingt bei (0,0)!! */
- if (root != 0 && tree[0].ob_x > 0)
- tree[0].ob_x = 0;
- if (root != 0 && tree[0].ob_y > 0)
- tree[0].ob_y = 0;
-
- box.g_x = tree[root].ob_x - 1;
- box.g_y = tree[root].ob_y - 1;
- box.g_w = tree[root].ob_width + 4;
- box.g_h = tree[root].ob_height + 4;
-
- wind_update(BEG_MCTRL);
- save_background(&box, &save);
- graf_mouse(ARROW, NULL);
-
- if (button == 0)
- button = 1;
- #ifdef __MTAES__
- graf_mkstate(&ev);
- m_x = ev.x;
- m_y = ev.y;
- but = ev.bstate;
- #else
- graf_mkstate(&m_x, &m_y, &but, &d);
- #endif
-
- if (but & button) /* Taste noch gedrückt? */
- but = 0; /* -> evnt_multi wartet auf Loslassen */
- else
- but = 1; /* -> Drücken */
-
- #ifdef __MTAES__
- objc_draw(tree, root, MAX_DEPTH, &box);
- #else
- objc_draw(tree, root, MAX_DEPTH, box.g_x, box.g_y, box.g_w, box.g_h);
- #endif
- olditem = -1;
- do
- {
- item = objc_find(tree, root, MAX_DEPTH, m_x, m_y);
- if ((item == root) || !valid_item(tree, item))
- item = -1;
-
- if (item != olditem)
- {
- if (olditem != -1)
- #ifdef __MTAES__
- objc_change(tree, olditem, 0, &box, tree[olditem].ob_state & (~SELECTED), TRUE);
- #else
- objc_change(tree, olditem, 0, box.g_x, box.g_y, box.g_w, box.g_h, tree[olditem].ob_state & (~SELECTED), TRUE);
- #endif
- if (item != -1)
- #ifdef __MTAES__
- objc_change(tree, item, 0, &box, tree[item].ob_state|SELECTED, TRUE);
- #else
- objc_change(tree, item, 0, box.g_x, box.g_y, box.g_w, box.g_h, tree[item].ob_state|SELECTED, TRUE);
- #endif
- }
- if (item != -1)
- {
- objc_offset(tree, item, &r.g_x, &r.g_y);
- r.g_w = tree[item].ob_width;
- r.g_h = tree[item].ob_height;
- }
- else
- {
- r.g_x = m_x;
- r.g_y = m_y;
- r.g_w = 1;
- r.g_h = 1;
- }
-
- #ifdef __MTAES__
- event = evnt_multi((MU_BUTTON | MU_M1),
- 1, button, but, /* ein Klick, links, s.o. */
- 1, &r, 0, &n,
- msg,
- 0L,
- &ev,
- &d, &d);
- m_x = ev.x;
- m_y = ev.y;
- kstate = ev.kstate;
-
- /* warten, bis die Taste wieder losgelassen wird */
- if (but == 1)
- evnt_button(1, button, 0, &ev);
- #else
- event = evnt_multi((MU_BUTTON | MU_M1),
- 1, button, but, /* ein Klick, links, s.o. */
- 1, r.g_x, r.g_y, r.g_w, r.g_h,
- 0, 0, 0, 0, 0,
- msg,
- 0L,
- &m_x, &m_y,
- &d, &kstate,
- &d, &d);
-
- /* warten, bis die Taste wieder losgelassen wird */
- if (but == 1)
- evnt_button(1, button, 0, &d, &d, &d, &d);
- #endif
-
- olditem = item;
- }
- while (!(event&MU_BUTTON));
-
- restore_background(&box, &save);
- wind_update(END_MCTRL);
-
- if (item == -1)
- item = 0;
- else
- tree[item].ob_state &= ~SELECTED;
-
- if (m2 != NULL)
- {
- if (m1 != m2)
- memcpy(m2, m1, sizeof(MENU));
- m2->mn_item = item;
- m2->mn_keystate = kstate;
- }
- return (item != 0);
- }
- }
-
-
- /*
- * Popup zur Laufzeit erzeugen.
- */
- int create_popup(POPUP *p, int anz, int maxlen, char *item)
- {
- char *text;
- int i;
-
- p->tree = (OBJECT *) cf_malloc((anz + 1) * sizeof(OBJECT), "create_popup", FALSE);
- if (p->tree == NULL)
- return FALSE;
-
- p->max_item = anz;
- if (maxlen == -1)
- p->item_len = (int)strlen(item);
- else
- p->item_len = maxlen;
-
- /* Box */
- p->tree[0].ob_next = -1;
- p->tree[0].ob_head = 1;
- p->tree[0].ob_tail = 1;
- p->tree[0].ob_type = G_BOX;
- p->tree[0].ob_flags = FL3DBAK;
- p->tree[0].ob_state = SHADOWED;
- p->tree[0].ob_spec.index = 0x00ff1100L; /* Rahmen, Farbe ... */
- p->tree[0].ob_x = 0;
- p->tree[0].ob_y = 0;
- p->tree[0].ob_width = p->item_len;
- p->tree[0].ob_height = 1;
-
- /* Speicher für String holen */
- text = strdup(item);
- if (text == NULL)
- return FALSE;
-
- /* 1. Eintrag */
- p->tree[1].ob_next = 0;
- p->tree[1].ob_head = -1;
- p->tree[1].ob_tail = -1;
- p->tree[1].ob_type = G_STRING;
- p->tree[1].ob_flags = (SELECTABLE|LASTOB);
- p->tree[1].ob_state = 0;
- p->tree[1].ob_spec.free_string = text;
- p->tree[1].ob_x = 0;
- p->tree[1].ob_y = 0;
- p->tree[1].ob_width = p->item_len;
- p->tree[1].ob_height = 1;
-
- p->akt_item = 1;
-
- for(i = 0; i <= p->akt_item; i++)
- rsrc_obfix(p->tree, i);
-
- return TRUE;
- }
-
-
- int free_popup(POPUP *p)
- {
- int i;
-
- if (p->tree == NULL)
- return FALSE;
- else
- {
- i = -1;
- do
- {
- i++;
- if (get_obtype(p->tree, i, NULL) == G_STRING)
- Mfree((char *)get_obspec(p->tree, i)); /* free_string freigeben */
- }
- while (!(p->tree[i].ob_flags & LASTOB));
- Mfree(p->tree);
- return TRUE;
- }
- }
-
-
- int append_popup(POPUP *p, char *item)
- {
- char *text;
- int i, state;
-
- if (p->tree == NULL)
- return FALSE;
-
- if (p->akt_item >= p->max_item)
- return FALSE;
-
- /* letztes wird vorletztes */
- p->tree[p->akt_item].ob_next = p->akt_item + 1;
- p->tree[p->akt_item].ob_flags = SELECTABLE;
-
- p->akt_item++;
-
- if (item[0] == '-')
- state = 0x0008;
- else
- state = 0x0000;
-
- /* Speicher für String holen */
- text = strdup(item);
- if (text == NULL)
- return FALSE;
-
- /* neues */
- p->tree[p->akt_item].ob_next = 0;
- p->tree[p->akt_item].ob_head = -1;
- p->tree[p->akt_item].ob_tail = -1;
- p->tree[p->akt_item].ob_type = G_STRING;
- p->tree[p->akt_item].ob_flags = (SELECTABLE|LASTOB);
- p->tree[p->akt_item].ob_state = state;
- p->tree[p->akt_item].ob_spec.free_string = text;
- p->tree[p->akt_item].ob_x = 0;
- p->tree[p->akt_item].ob_y = (p->akt_item - 1) * gl_hchar;
- p->tree[p->akt_item].ob_width = (p->item_len) * gl_wchar;
- p->tree[p->akt_item].ob_height = 1 * gl_hchar;
-
- /* Box */
- p->tree[0].ob_tail = p->akt_item;
- p->tree[0].ob_height = (p->akt_item) * gl_hchar;
-
- for(i = 0; i <= p->akt_item; i++)
- {
- /* zurück auf Zeichenkoor., damit der obfix klappt! */
- p->tree[i].ob_y /= gl_hchar;
- p->tree[i].ob_width /= gl_wchar;
- p->tree[i].ob_height /= gl_hchar;
- rsrc_obfix(p->tree, i);
- }
- return TRUE;
- }
-
-
- int do_popup(POPUP *p, int button)
- {
- int flag, p_x, p_y, d;
- MENU Menu,
- MData;
-
- Menu.mn_tree = p->tree;
- Menu.mn_menu = ROOT;
- Menu.mn_item = 0;
- Menu.mn_scroll = FALSE;
-
- #ifdef __MTAES__
- {
- EVNTDATA ev;
- graf_mkstate(&ev);
- p_x = ev.x;
- p_y = ev.y;
- }
- #else
- graf_mkstate(&p_x, &p_y, &d, &d);
- #endif
-
- flag = cf_menu_popup( &Menu, p_x, p_y, &MData, button, 0);
- return (flag ? MData.mn_item : 0);
- }
-
-
- int handle_popup(OBJECT *dial, int dial_obj, OBJECT *pop, int pop_obj, int mode)
- {
- char active_str[50] = "", s[50];
- int first, last, item, i, first_offset;
- int x, y;
- MENU m1, m2;
- GRECT r;
- int down_pop;
-
- if (pop == NULL)
- return -1;
-
- first = pop[pop_obj].ob_head;
- while (!valid_item(pop, first))
- first++;
-
- last = pop[pop_obj].ob_tail;
- while (!valid_item(pop, last))
- last--;
-
- /* falls erste Spalte z.B. Farbmarke */
- first_offset = first - pop[pop_obj].ob_head;
-
- item = first;
- down_pop = FALSE;
-
- if (dial != NULL)
- {
- /* Popup-Typ ermitteln */
- down_pop = (get_obtype(dial, dial_obj, NULL) == G_BOXCHAR);
-
- if (!down_pop)
- {
- /* Zunächst das aktuelle, im Dialog eingetragene Popup-Item suchen */
- get_string(dial, dial_obj, active_str);
- item = first;
- while (item <= last)
- {
- get_string(pop, item, s);
- if (strcmp(active_str, s) == 0)
- break;
- item++;
- }
- if (item > last) /* nicht gefunden */
- item = first;
- }
- }
-
- switch (mode)
- {
- case POP_OPEN:
- /* Position des Popups ermitteln */
- if (dial != NULL)
- {
- objc_offset(dial, dial_obj, &x, &y);
- if (down_pop)
- x -= (pop[1].ob_width - dial[dial_obj].ob_width);
- else
- {
- /* mehrspaltiges Popups? */
- if (pop[pop_obj].ob_height <= ((item - first) * gl_hchar))
- {
- get_objframe(pop, item, &r);
- x -= r.g_w;
- item -= (pop[pop_obj].ob_height / gl_hchar);
- }
- }
-
- /* außerhalb des Bildschirms? */
- get_objframe(pop, pop_obj, &r);
-
- if (x < gl_desk.g_x)
- x = gl_desk.g_x;
- if ((x + r.g_w) > (gl_desk.g_x + gl_desk.g_w))
- x = (gl_desk.g_x + gl_desk.g_w) - r.g_w;
-
- i = (last - item + 1) * gl_hchar;
- if ((y + i) > (gl_desk.g_y + gl_desk.g_h))
- y = (gl_desk.g_y + gl_desk.g_h) - i;
-
- i = (item - first) * gl_hchar;
- if (y - i < gl_desk.g_y)
- y = gl_desk.g_y + i;
-
- }
- else
- {
- #ifdef __MTAES__
- EVNTDATA ev;
- graf_mkstate(&ev);
- x = ev.x;
- y = ev.y;
- #else
- graf_mkstate(&x, &y, &i, &i);
- #endif
- get_objframe(pop, item, &r);
- x -= r.g_w / 2;
- y -= r.g_h / 2;
- if (first_offset > 0)
- y -= (first_offset * gl_hchar);
- }
- m1.mn_tree = pop;
- m1.mn_menu = pop_obj;
- m1.mn_item = item;
- i = cf_menu_popup(&m1, x, y, &m2, 1, first_offset);
- if (i != 0)
- item = m2.mn_item;
- else
- item = 0;
- break;
-
- case POP_CYCLE:
- i = 0;
- do
- {
- item++;
- i++;
- if (item > last)
- item = first;
- }
- while(((pop[item].ob_state & DISABLED) ||
- !(pop[item].ob_flags & SELECTABLE)) &&
- i <= last - first);
-
- if (i > last - first)
- item = 0;
- break;
-
- default:
- debug("\ahandle_popup: unbekannter Modus %d.\n", mode);
- }
-
- /* Text des neuen Popup-Items in den Dialog eintragen und neu zeichnen */
- if ((!down_pop) && (item > 0) && (dial != NULL))
- {
- get_string(pop, item, s);
- set_string(dial, dial_obj, s);
- get_objframe(dial, dial_obj, &r);
- #ifdef __MTAES__
- objc_draw(dial, dial_obj, 1, &r);
- #else
- objc_draw(dial, dial_obj, 1, r.g_x, r.g_y, r.g_w, r.g_h);
- #endif
- }
-
- return item;
- }
-